package cn.sdxx.qddata.controller;

import cn.sdxx.qddata.common.R;

import cn.sdxx.qddata.entity.User;
import cn.sdxx.qddata.security.JwtToken;
import cn.sdxx.qddata.service.UserService;
import cn.sdxx.qddata.utils.JwtTokenUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@Slf4j
@Api(tags = "User模块")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @ApiOperation(value = "检查用户名是否可用")
    @ApiImplicitParam(name = "username", value = "需要检查的用户名", required = true)
    @GetMapping("/check")
    public R checkUsername(@RequestParam(value = "username") String username) {
        log.info("CHECK USERNAME --> {}", username);
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getUsername, username);
        User user = userService.getOne(lqw);
        if (user != null) {
            //该username已经占用了
            return R.fail("此用户名已经存在");
        }
        return R.success("此用户名可以使用");

    }

    @ApiOperation(value = "用户注册")
    @PostMapping("/reg")
    public R register(@RequestBody User user) {
        log.info("REGISTER USER --> {}", user);
        //检查username
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getUsername, user.getUsername());
        User userEx = userService.getOne(lqw);
        if (userEx != null) {
            //该username已经占用了
            return R.fail("注册失败！用户名" + user.getUsername() + "被占用");
        }
        //检查phone
        LambdaQueryWrapper<User> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(User::getPhone, user.getPhone());
        userEx = userService.getOne(lqw2);
        if (userEx != null) {
            //该phone已经占用了
            return R.fail("注册失败！手机号" + user.getPhone() + "被占用");
        }
        //检查密码是否符合规则
        String userPassword = user.getPassword();
        if (userPassword == null || userPassword.length() < 6 || userPassword.length() > 16) {
            return R.fail("注册失败！密码长度必须是6-16位");
        }

        //开始注册
        user.setId(null);
        boolean b = userService.save(user);
        if (b) {
            return R.success("注册成功！");
        }
        return R.fail("注册失败！");
    }


    /**
     * 1.传统登录
     * 前端发送登录请求 => 接口部分获取用户名密码 => 程序员在接口部分手动控制
     * 2.shiro登录
     * 前端发送登录请求 => 接口部分获取用户名密码 => 通过subject.login =>  realm域的认证方法
     */
    @ApiOperation(value = "用户登录")
    @PostMapping("/login")
    public R login(User user) {
        if (user.getUsername() == null || user.getPassword() == null) {
            return R.fail("账号或密码不能为空");
        }
        log.info("USER 开始登录 --> {}", user);
//        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//        lqw.eq(User::getUsername, user.getUsername()).eq(User::getPassword, user.getPassword());
//        User userAccount = userService.getOne(lqw);
//        if(userAccount!=null){
        try {
            String usernameJWT = jwtTokenUtils.generateToken(user.getUsername());
            JwtToken jwtToken = new JwtToken(usernameJWT);
            // 让 shiro登录
            Subject subject = SecurityUtils.getSubject();
            subject.login(jwtToken);
            //获取session，让redis不缓存失败的登录
            //  subject.getSession(false);
            //登录成功，返回jwt
//            Object att = subject.getSession().getAttribute("user.getUsername()");
            return R.success("登录成功！", usernameJWT);
        } catch (AuthenticationException e) {
            return R.fail("登录失败！用户名或密码错误");
        }


    }

    @ApiOperation("注销登录")
    @GetMapping("/logout")
    public R logout() {
        SecurityUtils.getSubject().logout();
        return R.success("用户已注销");
    }

    @ApiOperation(value = "按用户名查询，分页列出用户")
    @GetMapping("/list")
    @RequiresAuthentication
    public R list(@RequestParam(required = false, value = "pageNo", defaultValue = "1") int pageNo,
                  @RequestParam(required = false, value = "pageSize", defaultValue = "5") int pageSize,
                  @RequestParam(required = false, value = "username") String username) {
        log.info("CHECK USERNAME --> {}", username);

        //分页构造器
        Page<User> pageInfo = new Page<>(pageNo, pageSize);
        //条件构造器
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(username != null, User::getUsername, username);
        //添加排序条件，根据id进行排序
        queryWrapper.orderByAsc(User::getId);
        userService.page(pageInfo, queryWrapper);
        log.info("pageInfo --> {}", pageInfo);
        return R.success(pageInfo);

    }

    @ApiOperation(value = "根据id删除用户")
    @ApiImplicitParam(name = "id", value = "用户的id", required = true)
    @DeleteMapping()
    @RequiresAuthentication
    public R deleteUser(@RequestParam("id") String id) {
        log.info("删除，id为：{}", id);

        boolean b = userService.removeById(id);
        if (b) {
            return R.success("用户删除成功");
        }
        return R.success("用户删除失败");
    }

    @ApiOperation(value = "获取当前用户信息")
    @GetMapping("/info")
    @RequiresAuthentication
    public R getUserInfo() {
        log.info("获取用户id的信息!!!");
        Object principal = SecurityUtils.getSubject().getPrincipal();
        return R.success(principal);
    }

    @ApiOperation(value = "根据id获取某个用户信息")
    @GetMapping("/info/{id}")
    @RequiresAuthentication
    public R getUserInfoById(@PathVariable("id") Long id) {
        User user = userService.getById(id);
        return R.success(user);
    }


    @ApiOperation(value = "修改头像")
    @PostMapping("/avatar")
    @RequiresAuthentication
    public R updateUserAvatar(@RequestBody  User user) {
        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.set(!user.getAvatar().isEmpty(),User::getAvatar,user.getAvatar());
        luw.eq(user.getId()!=null,User::getId,user.getId());
        boolean b = userService.update(luw);
        if(b){
            return R.success("更新头像成功！");
        }
        return R.fail("更新头像失败！");

    }

    @GetMapping("/hello")
    @RequiresAuthentication
    public R hello() {
        Object principal = SecurityUtils.getSubject().getPrincipal();
        System.out.println(principal);
        System.out.println("hello");
        return R.success(principal);
    }


}
